package pers.vic.blog.module.zbl.controller;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import pers.vic.blog.module.front.controller.BaseFrontController;
import pers.vic.blog.module.zbl.model.FileModel;
import pers.vic.blog.module.zbl.model.Remind;
import pers.vic.boot.util.CommonUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author Vic.xu
 * @description: 学生的临时操作controller
 * @date: 2020/7/12 0012 11:20
 */
@Controller
@RequestMapping("/student")
public class ZblStudentController extends BaseFrontController {

    @Value("${zbl.upload.path}")
    private String filepath = "/";

    @Value("${zbl.upload.password}")
    private String password;

    /**
     * 已经存在的文件
     */
    public static Set<String> fileSet = new HashSet<>();


    @GetMapping("/files")
    public String list(Model model) {
        List<FileModel> list = new ArrayList<FileModel>();
        new File(filepath).listFiles(new FileFilter() {

            @Override
            public boolean accept(File pathname) {
                String fileName = pathname.getName();
                long size = pathname.length();
                list.add(new FileModel(fileName, size));
                fileSet.add(fileName);
                return false;
            }
        });
        model.addAttribute("files", list);
        return "zbl/files";
    }

    /**
     * 上传
     */
    @PostMapping("upload")
    public String upload(String studentno, MultipartFile file, RedirectAttributes attr) {
        try {
            String originalFileName = file.getOriginalFilename();

            String filename = studentno + "." + StringUtils.substringAfter(originalFileName, ".");

            FileUtils.copyInputStreamToFile(file.getInputStream(), new File(filepath, filename));
            attr.addFlashAttribute(Remind.success());
        } catch (Exception e) {
            attr.addFlashAttribute(Remind.danger().setMessage(e.getMessage()));
        }
        return "redirect:/student/files";
    }

    public static void main(String[] args) {
        String s = "asd.123";
        System.out.println(StringUtils.substringAfter(s, "."));
    }


    /**
     * 流下载文件
     */
    @RequestMapping(value = "/download/{filename}", method = RequestMethod.GET)
    public void get(HttpServletResponse response, @PathVariable String filename) {
        try {
            File file = new File(filepath, filename);
            if (!file.exists()) {
                CommonUtils.writeJson("不存在的文件", response);
                return;
            }
            response.setHeader("content-type", "application/octet-stream");
            response.setContentType("application/octet-stream");
            response.setHeader("Content-disposition", "attachment; filename=\"" + file.getName() + "\"");
            FileCopyUtils.copy(new FileInputStream(file), response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 登录
     * @param password
     * @param attr
     * @return
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login(String password, RedirectAttributes attr) {
        if(StringUtils.equals(this.password, password)){
            attr.addFlashAttribute(Remind.success());
            setSessionAttribute("zbl", true);
        }else {
            setSessionAttribute("zbl", false);
            attr.addFlashAttribute(Remind.danger().setMessage("密码错误"));
        }
        return "redirect:/student/files";
    }

    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public String logout(RedirectAttributes attr) {
        setSessionAttribute("zbl", false);
        return "redirect:/student/files";
    }


    /**
     * 删除文件
     * @param filename
     * @param attr
     * @return
     */
    @GetMapping("/delete/{filename}")
    public String delete(@PathVariable String filename, RedirectAttributes attr){
        checkLogin();
        File file = new File(filepath, filename);
        FileUtils.deleteQuietly(file);
        attr.addFlashAttribute(Remind.success());
        return "redirect:/student/files";
    }


    public boolean checkLogin(){
        Boolean zbl = getSessionAttribute("zbl");
        if(zbl == null || !zbl){
            CommonUtils.writeJson("请先登录", response);
            return false;
        }
        return true;
    }


    @RequestMapping(value = "/downloads", method = RequestMethod.GET)
    public void downloads(String password) throws IOException {
        checkLogin();
        byte[] data = zip();
        response.reset();
        response.setHeader("Content-Disposition", "attachment; filename=\"all.zip\"");
        response.addHeader("Content-Length", "" + data.length);
        response.setContentType("application/octet-stream; charset=UTF-8");
        IOUtils.write(data, response.getOutputStream());
    }

    public byte[] zip() {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outputStream);
        new File(filepath).listFiles(new FileFilter() {

            @Override
            public boolean accept(File file) {
                try (FileInputStream in = new FileInputStream(file);
                     BufferedInputStream bis = new BufferedInputStream(in)) {
                    zip.putNextEntry(new ZipEntry(file.getName()));
                    byte[] buffer = new byte[1024];
                    int count = -1;
                    while ((count = bis.read(buffer)) != -1) {
                        zip.write(buffer, 0, count);
                    }
                    zip.closeEntry();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return false;
            }
        });
        IOUtils.closeQuietly(zip);
        return outputStream.toByteArray();
    }


}
